﻿#pragma once

#include "base/core/singleton.h"
#include "base/core/object_pool.h"
#include "base/core/gamemath.h"
#include "Scene/SceneMgr.h"
#include "Common/ComDefine.pb.h"
#include "Common/DuplicateDefine.h"
#include "IDuplicate.h"
#include "Duplicate/activity/TowerDuplicate.h"
#include "Duplicate/activity/GuardDuplicate.h"
#include "Duplicate/activity/CloudDuplicate.h"
#include "Duplicate/new/NewDuplicate.h"
#include "Duplicate/brush/BrushMonsMgr.h"
#include "Duplicate/single/SingleDuplicateA.h"
#include "Duplicate/story/StoryDuplicate.h"
#include "Duplicate/ladder/LadderDuplicate.h"
#include "Duplicate/arena/ArenaDuplicate.h"
#include "Duplicate/union/UnionHomeDuplicate.h"
#include "Duplicate/activity/PestilenceDuplicate.h"
#include "Duplicate/union/UnionDungeonDuplicate.h"
#include "Duplicate/camp/CampDuplicate.h"
#include "Duplicate/compete/CompeteDuplicate.h"
#include "Duplicate/guide/GuideDuplicate.h"
#include "Common/ActivityDefine.h"
#include "Script/ScriptMgr.h"
#include "Common/UnionDefine.h"

using namespace luabridge;

//副本场景 sceneid - IDuplicate*
typedef std::unordered_map < uint32_t, IDuplicate* > DuplicateSceneMap;

class DuplicateMgr : public IServerMessageHandler, public IEventExecuteSink, public ManualSingleton<DuplicateMgr>
{
	friend class ManualSingleton < DuplicateMgr > ;
public:
	DuplicateMgr();
	~DuplicateMgr();

	bool Init();
	void UnInit();
	//创建副本
	IDuplicate *MakeDuplicate(uint32_t nDuplicateID,uint32_t nSceneID);
	//释放副本
	void FreeDuplicate(IDuplicate *pDuplicate);
	//回收副本
	bool RecycleDuplicate(IDuplicate *pDuplicate);
	//获取副本
	IDuplicate *GetDuplicate(uint32_t nSceneID);
public:
	//////////////////////////////////////////////////////////////////////////
	virtual void OnExecute(uint16_t nEventID, uint64_t nSrcID, uint8_t bySrcType, void *pContext, int32_t nLen);
	////////////////////////////////  IServerMessageHandler //////////////////////////////////////////
	virtual void		onServerMessage(uint32_t actionId, RECV_PACKAGE &package);
	virtual const char* getServerHandlerDebugInfo(void){ return "DuplicateMgr::onServerMessage"; };
	//中心服返回逻辑服创建副本场�?
	IDuplicate* CenterToLogicCreateDupSceneRsp(uint32_t sceneId,CreateSceneParamProto &proto);
	//中心服通知逻辑服玩家进副本
	void CenterToLogicNotifyEnter(RECV_PACKAGE &package);
	//通知中心服玩家进入副�?
	void NotifyCenterEnterDuplicate(uint32_t nSceneID, uint64_t cid,int32_t result);
	//通知中心服玩家离开副本
	void NotifyCenterLeaveDuplicate(uint32_t nSceneID, uint64_t cid,int8_t byType = 0);
	//通知中心服副本开�?
	void NotifyCenterDuplicateBegin(uint32_t nSceneID);
	//通知中心服副本结�?
	void NotifyCenterDuplicateEnd(uint32_t nSceneID,int32_t result);
	//逻辑服返回中心服副本销�?
	void DuplicateDestoryRsp(uint32_t nSceneID);
	//通知中心服通关副本
	void NotifyCenterPassDuplicate(CharIDType charId, uint32_t dupId, int8_t byTeam);
	//工会解散处理（工会驻地场景处理）
	void OnUnionDismiss(uint32_t unionId,uint32_t sceneId);
	//踢出玩家（工会踢出成员）
	void OnUnionKickMem(CharIDType charId,uint32_t sceneId);
	//云端试炼结束
	void OnCloudEnd(uint32_t unionId,uint32_t sceneId);
	//绑定工会驻地
	void OnBindUnionHome(uint32_t unionId, uint32_t sceneId);
	//工会活动状态
	void OnUnionActivityState(uint32_t actId,int32_t state,SUnionActParam &param);
	//工会等级更新
	void OnUnionLevel(uint32_t unionId,uint32_t sceneId,int32_t unionLev);
	//工会首领外观
	void OnUnionLeaderFacade(uint32_t sceneId, CharOutward *pNpcFacade);
	//工会地宫关闭
	void OnUnionDungeonClose(uint32_t unionId, uint32_t sceneId);
	//离开队伍
	void OnLeaveTeam(CharIDType charId,uint32_t sceneId);
	//离开房间
	void OnLeaveRoom(CharIDType charId, uint32_t sceneId);
	//副本重连
	void OnReconnect(Player *pPlayer);
	//创建新手引导副本
	IDuplicate *CreateGuideDup(uint32_t sceneId,uint32_t mapId, const CreateSceneParamProto &proto);
public:
	///////////////////////////  LUA 数据相关///////////////////////////////////////////////
	//获取瘟疫之战配置
	bool GetPestilenceLuaCfg(PestilenceCfg &cfg);
	//加载副本LUA配置
	bool LoadLuaCfg(IDuplicate *pDuplicate, int8_t brushType, uint32_t beginStep = 0);
private:
	//普通刷怪LUA配置
	bool CommonLuaCfg(uint32_t nDuplicateID, uint32_t nSceneID, uint32_t nMapId, AllBrushDataCfg *pCfgData, luabridge::LuaRef &refLevel);
	//普通进入区域刷怪信息
	void CommonEnterAreaInfo(uint32_t nDuplicateId, uint32_t nMapId, luabridge::LuaRef &refEnterArea, AllBrushDataCfg *pCfgData);
	//普通死亡刷新信息
	void CommonDieBrushInfo(uint32_t nDuplicateId, uint32_t mapId, luabridge::LuaRef &refDieBrush, AllBrushDataCfg *pCfgData);
	//普通定时刷新信息
	void CommonTimeBrushInfo(luabridge::LuaRef &refTimeBrush, AllBrushDataCfg *pCfgData);

	//塔防刷怪LUA配置
	bool TowerLuaCfg(uint32_t nDuplicateID, uint32_t nSceneID, uint32_t nMapId, AllBrushDataCfg *pCfgData, luabridge::LuaRef &refTower);
	//塔防定时刷新信息
	void TowerTimeBrushInfo(uint32_t dupId, uint32_t sceneId, uint32_t mapId, luabridge::LuaRef &refTimeBrush, AllBrushDataCfg *pCfgData);

	//守护刷怪LUA配置
	bool GuardLuaCfg(uint32_t nDuplicateID, uint32_t nSceneID,uint32_t nMapId, AllBrushDataCfg *pCfgData, luabridge::LuaRef &refGuard);
	//守护定时刷新信息
	void GuardTimeBrushInfo(uint32_t dupId, uint32_t sceneId, luabridge::LuaRef &refTimeBrush, AllBrushDataCfg *pCfgData);

	//副本动态阻挡LUA配置
	bool DupBlckLuaCfg(uint32_t nDuplicateID, uint32_t nSceneID, uint32_t nMapId, AllBlockDataCfg *pCfgData, luabridge::LuaRef &refBlock);
	//阻挡进入区域信息
	void DupBlockEnterAreaInfo(luabridge::LuaRef &refBlock, uint32_t nDuplicateId, uint32_t nMapId, AllBlockDataCfg *pCfgData);
	//阻挡怪物死亡信息
	void DupBlockDieInfo(luabridge::LuaRef &refBlock, uint32_t nDuplicateId, uint32_t nMapId, AllBlockDataCfg *pCfgData);
	//阻挡怪物出生信息
	void DupBlockBornInfo(luabridge::LuaRef &refBlock, uint32_t nDuplicateId, uint32_t nMapId, AllBlockDataCfg *pCfgData);
	//阻挡使用物件信息
	void DupBlockUseThingInfo(luabridge::LuaRef &refBlock, uint32_t nDuplicateId, uint32_t nMapId, AllBlockDataCfg *pCfgData);
	//设置怪物类型数量
	void SetMonsTypeNum(int8_t monsType, uint32_t monsId, int32_t monsNum, MAP_INT8_MAP_UINT32_UINT32 &mapMonsTypeNum);

	//工会刷怪LUA配置
	bool UnionLuaCfg(uint32_t nDuplicateID, uint32_t nSceneID, uint32_t nMapId, AllBrushDataCfg *pCfgData, luabridge::LuaRef &refUnion);
	//工会刷怪波数信息
	bool UnionBrushWaveInfo(uint32_t nDuplicateID, uint32_t nSceneID, uint32_t nMapId, luabridge::LuaRef &refWave, AllBrushDataCfg *pCfgData);
	//工会刷小波怪
	bool UnionBrushMonsInfo(uint32_t nDuplicateId, uint32_t nMapId, luabridge::LuaRef &refMons, VecUnionMonCfg &vecMons);
	//工会刷boss怪信息
	bool UnionBrushBossMonsInfo(uint32_t nDuplicateId, uint32_t nMapId, luabridge::LuaRef &refBossMons, VecUnionBossMonCfg &vecBossMons);

	//新手刷怪LUA配置
	bool NewLuaCfg(uint32_t nDuplicateID, uint32_t nSceneID, uint32_t nMapId, AllBrushDataCfg *pCfgData, luabridge::LuaRef &refNew, uint32_t beginStep);
	//新手步骤刷挂LUA配置
	bool NewStepLuaCfg(uint32_t nDuplicateID, uint32_t nSceneID, uint32_t nMapId, AllBrushDataCfg *pCfgData, luabridge::LuaRef &refStep);
	//副本怪物进入区域
	bool MonsEnterAreaCfg(uint32_t nDuplicateID, uint32_t nSceneID, uint32_t nMapId,int32_t brushType, AllBrushDataCfg *pCfgData, luabridge::LuaRef &refEnterAreaCfg);
private:
	ObjectPool<NewDuplicate> *m_pNewDuplicatePool;
	ObjectPool<StoryDuplicate> *m_pStoryDuplicatePool;
	ObjectPool<TowerDuplicate> *m_pTowerDuplicatePool;
	ObjectPool<GuardDuplicate> *m_pGuardDuplicatePool;
	ObjectPool<SingleDuplicateA> *m_pSingleDuplicateAPool;
	ObjectPool<LadderDuplicate> *m_pLadderDuplicatePool;
	ObjectPool<ArenaDuplicate> *m_pArenaDuplicatePool;
	ObjectPool<UnionHomeDuplicate> *m_pUnionHomeDuplicatePool;
	ObjectPool<PestilenceDuplicate> *m_pPestilenceDuplicatePool;	
	ObjectPool<CloudDuplicate> *m_pCloudDuplicatePool;
	ObjectPool<UnionDungeonDuplicate> *m_pUnionDungeonDuplicatePool;
	ObjectPool<CampDuplicate> *m_pCampDuplicatePool;
	ObjectPool<CompeteDuplicate> *m_pCompeteDuplicatePool;
	ObjectPool<GuideDuplicate> *m_pGuideDuplicatePool;	
	//副本场景
	DuplicateSceneMap m_mapDuplicateScene;
};


#define g_MakeDuplicateMgr() (DuplicateMgr::Instance())
#define g_GetDuplicateMgr()  (DuplicateMgr::GetInstance())
#define g_DelDuplicateMgr()  (DuplicateMgr::Destroy())
